package priv.blackbibo.application.service;

import android.app.Service;
import android.content.Intent;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * Created by black on 2019-12-17.
 */
public class SongListLoadService extends Service implements Runnable {
    private static final String TAG = "SongListLoadService";

    private static final String cacheFileName = "songs";

    public static final String ACTION = "priv.blackbibo.application.service.SongListLoadService";

    public SongListLoadService() {
        Log.d(TAG, "SongListLoadService: init");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void run() {
        load();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        load();
        /**
         * 没有判断状态，当做所有任务都已经完成
         */
        sendBrodcast();
        return START_NOT_STICKY;
    }

    private void load() {
        File file = new File("/");
        File songsFolder = findFile(file, "/songs");
        List<Map<String, String>> list = new LinkedList<>();
        if (songsFolder.exists()) {
            if (songsFolder.isDirectory()) {
                File[] songsFile = songsFolder.listFiles();
                if (songsFile == null) {
                    //pass
                } else {
                    int index = 1;
                    for (File song : songsFile) {
                        if (song.getName().contains(".mp3") || song.getName().contains(".flac")) {
                            MediaMetadataRetriever mrr = new MediaMetadataRetriever();
                            mrr.setDataSource(this, Uri.parse(song.getAbsolutePath()));
                            Map<String, String> map = new HashMap<>();
                            map.put("index", String.valueOf(index++));
                            map.put("path", song.getAbsolutePath());
                            String title = mrr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
                            if (title == null || title.equals("")) {
                                title = song.getName().replace(".mp3", "").replace(".flac", "");
                            }
                            map.put("name", title);
                            list.add(map);
                        }
                    }
                    saveSongIntoXml(list);
                }
            }
        }
    }


    public File findFile(File file, String filename) {
        Log.d(TAG, "findFile: check " + file.getAbsolutePath());
        if (file.getAbsolutePath().endsWith(filename)) {
            return file;
        } else {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files != null) {
                    for (File sub : files) {
                        if (!sub.isDirectory()) {
                            continue;
                        }
                        if (sub.getAbsolutePath().split("/").length > 4) {
                            continue;
                        }
                        File rs = findFile(sub, filename);
                        if (rs != null) {
                            return rs;
                        }
                    }
                }
            }
        }
        return null;
    }


    public void saveSongIntoXml(List<Map<String, String>> list) {
        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
            Document document = builder.newDocument();
            Element songs = document.createElement("songs");
            for (Map<String, String> map : list) {

                String index = map.get("index");
                String path = map.get("path");
                String name = map.get("name");

                Element song = document.createElement("song");
                Element indexDoc = document.createElement("index");
                indexDoc.setTextContent(index);
                Element pathDoc = document.createElement("path");
                pathDoc.setTextContent(path);
                Element nameDoc = document.createElement("name");
                nameDoc.setTextContent(name);
                song.appendChild(indexDoc);
                song.appendChild(pathDoc);
                song.appendChild(nameDoc);
                songs.appendChild(song);
            }
            document.appendChild(songs);

            File folder = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
            File file = new File(folder.getAbsolutePath() + "/" + cacheFileName + ".xml");

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.transform(new DOMSource(document), new StreamResult(file));
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }

    public void sendBrodcast() {
        Intent intent = new Intent();
        intent.setAction(ACTION);
        sendBroadcast(intent);
    }
}
